#include "ArrayList.h"
using namespace std;
template<class T>
ArrayList<T>::ArrayList(int initialCapcity){
    if(initialCapcity<1){
        ostringstream s;
        s<<"Initial capacity = "<<initialCapcity<<" must be > 0";
        throw illegalParameterValue(s.str());
    }
    arrayLength = initialCapcity;
    element = new T[arrayLength];
    listSize = 0;
}

template<class T>
ArrayList<T>::ArrayList(const ArrayList<T>& theList){
    arrayLength = theList.arrayLength;
    listSize = theList.listSize;
    element = new T[arrayLength];
    copy(theList,theList+listSize,element);
}
template<class T>
void ArrayList<T>::checkIndex(int theIndex) const{
    if(theIndex<0||theIndex>=listSize){
        ostringstream s;
        s<<"index = "<<theIndex<<" size = "<<listSize;
        throw illegalIndex(s.str());
    }
}
template <class T>
T& ArrayList<T>::get(int theIndex) const{
    checkIndex(theIndex);
    return element[theIndex];
}

template<class T>
int ArrayList<T>::indexOf(const T &theElement) const {
    int theIndex = (int)(find(element,element+listSize,theElement)-element);
    if(theIndex==listSize){
        return -1;
    }else{
        return theIndex;
    }
}

template<class T>
void ArrayList<T>::erase(int theIndex){
    checkIndex(theIndex);
    copy(element+theIndex+1,element+listSize,element+theIndex);
    element[--listSize].~T();
}

template<class T>
void ArrayList<T>::insert(int theIndex, const T &theElement) {
    if(theIndex<0||theIndex>listSize){
        ostringstream s;
        s<<"index = "<<theIndex<<" size = "<<listSize;
        throw illegalIndex(s.str());
    }
    if(listSize==arrayLength){
        changeLength1D(element,arrayLength,2*arrayLength);
        arrayLength*=2;
    }
    copy_backward(element+theIndex,element+listSize,element+listSize+1);
    element[theIndex] = theElement;
    listSize = listSize+1;
}

template<class T>
void ArrayList<T>::output(ostream &out) const {
    copy(element,element+listSize,ostream_iterator<T>(out," "));
}

template<class T>
void ArrayList<T>::set(int theIndex, const T &theElement) {
//    copy(&theElement,&theElement+1,element+theIndex);
    element[theIndex] = theElement;
}

template<class T>
void ArrayList<T>::push_back(const T &theElement) {
    if(listSize==arrayLength){
        changeLength1D(element,arrayLength,2*arrayLength);
        arrayLength*=2;
    }
    element[listSize] = theElement;
    listSize++;
}

template<class T>
void ArrayList<T>::clear() {
    for(int i = 0;i<arrayLength;i++){
        element[i].~pairType();
    }
    listSize = 0;
}

template<class T>
void ArrayList<T>::reSize(int theSize) {
    changeLength1D(element,arrayLength,theSize);//数据复制
    if(theSize<listSize){
        listSize = theSize;
    }//else theSize>=listSize, listSize不变
}


template<class T>
ostream &operator<<(ostream &out, const ArrayList<T> &x) {
    x.output(out);
    return out;
}